package com.intel.factorytest.log;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import android.util.Log;

import com.intel.factorytest.util.SDCardUtil;

public class LogWriter {
    
    private static LogWriter instance;
    
    public static final String LogFileNameTag = "logfilename";

    private static final String TAG = "LogWritter";
    private static final String sep = System.getProperty("file.separator", "/");
    // [/storage/emulated/0, /storage/sdcard1, /storage/usbcard1]
    private static String LogDir = SDCardUtil.getExternalStoragePath();
    private static final String LogFilePrefix = "MAT_TEST_";
    // test level
    public static final String LogType_SingleTest = "Single";
    public static final String LogType_SystemTest = "System";
    public static final String LogType_PcbaTest = "Pcba";
    
    private static String CurrentLogType = LogType_SingleTest;
    private static String CurrentTimestamp = "";
    
    private static final String LogExtension = ".log";
    
    private static boolean isEnable = true;
    
    private LogWriter() {
        
    }
    
    @SuppressWarnings("unused")
    private static synchronized LogWriter getInstance() {
        if (instance == null) {
            instance = new LogWriter();
        }
        return instance;
    }
    
    public static String getFileName(String logType) {
        StringBuilder sb = new StringBuilder("");
        
        File logDir = new File(LogDir);
        if (!logDir.exists()) {
            Log.i(TAG, "Directory " + LogDir + " doesn't exist! please check.");
            return sb.toString();
        }
        Log.i(TAG,"tangjun LogDir=" + LogDir);
        
        CurrentLogType = logType;
        
        sb.append(LogDir).append(sep).append("logs").append(sep);
        
        long timestamp = System.currentTimeMillis();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA);
        CurrentTimestamp = sdf.format(new Date(timestamp));
        
        // clear logs
        deleteLogs(new File(LogDir + sep + "logs"));
        if (!LogDir.equals(SDCardUtil.INTERNAL_STORAGE_PATH)) {
            deleteLogs(new File(SDCardUtil.INTERNAL_STORAGE_PATH + sep + "logs"));
        }
        
        String filename = sb.append(LogFilePrefix).append(CurrentLogType).append("_").append(CurrentTimestamp).append(LogExtension).toString();
        
        Log.i(TAG,"tangjun getFileName=" + filename);
        return filename;
    }
    
    /**
     * 如果外部存储卡存在，则优先记录在外部存储卡上，如果不存在，则记录在内部存储卡上
     * 
     * @param context
     * @return
     */
    public static String initLogsDir(String logDir) {
        if (logDir != null && logDir.trim().length() != 0) {
            LogDir = logDir;
            Log.i(TAG,"tangjun LogWriter:LogDir=" + LogDir);
        }
        
        return LogDir;
    }
/*    
    public static void write(String fileName, TestCase tc) throws IOException {
        
        if (!isEnable()) {
            Log.i(TAG,"tangjun LogWriter is disable!");
            return;
        }
        // log to TF card
        Log.i(TAG, "fileName: " + fileName);
        log2TFCard(fileName, tc);
        
        // log to internal storage card
        if (!LogDir.equals(SDCardUtil.INTERNAL_STORAGE_PATH)) {
            String fn = fileName.substring(fileName.lastIndexOf('/'));
            String fileName_eMMC = SDCardUtil.INTERNAL_STORAGE_PATH + sep + "logs" + sep + fn;
            Log.i(TAG, "fileName_eMMC: " + fileName_eMMC);
            log2eMMC(fileName_eMMC, tc);
        }
    }
    
    private static void log2eMMC(String fileName, TestCase tc) throws IOException {
        log2TFCard(fileName, tc);
    }

    private static void log2TFCard(String fileName, TestCase tc) throws IOException {
        if (tc == null || fileName == null || fileName.trim().length() == 0) {
            System.out.println("tangjun tc=" + tc + "filename=" + fileName);
            return;
        }
        Log.i(TAG, "LogDir: " + LogDir);
        File logDir = new File(LogDir);
        if (!logDir.exists()) {
            Log.i(TAG, "Directory " + LogDir + " doesn't exist! please check.");
            return;
        } else {
            File logs = new File(LogDir + sep + "logs");
            if (!logs.exists()) {
                logs.mkdir();
            }
        }
        
        BufferedWriter writer = null;
//        try {
            File logFile = new File(fileName);
            if (!logFile.exists()) {
                if (logFile.createNewFile()) {
                    Log.i(TAG,"tangjun create log file [" + fileName + "] success");
                } else {
                    Log.i(TAG,"tangjun fail to create log file ");
                }
            }

            StringBuilder contentBuilder = new StringBuilder();
            StringBuilder tabBuilder = new StringBuilder();
            int tabCount = 60; // 总共60个字符长度
            int nameLen = tc.testCaseName.length();
            if (nameLen < tabCount) {
                for (int i = nameLen; i <= tabCount; i++) {
                    tabBuilder.append(" ");
                }
            }
            contentBuilder.append(tc.testCaseName).append(tabBuilder.toString()).append(tc.testResult ? "Pass" : "Fail");
            contentBuilder.append("\n");

            writer = new BufferedWriter(new OutputStreamWriter(
                    new FileOutputStream(new File(fileName), true)));
            Log.i(TAG,"tangjun write content="
                    + contentBuilder.toString());
            writer.write(contentBuilder.toString());
            writer.flush();
            
            if (writer != null) {
                writer.close();
            }
    }
*/    
    private static void deleteLogs(File logDir) {
        try {
            File[] logs = logDir.listFiles(new FilenameFilter() {
                
                @Override
                public boolean accept(File dir, String filename) {
                    // filename format: MAT_TEST_Single_20010119000405.log
                    if (filename.startsWith(LogFilePrefix)) {
                        String logType = filename.split("_")[2];
                        String timestamp = filename.split("_")[3].split("\\.")[1];
                        if (CurrentLogType.equals(logType) && !CurrentTimestamp.equals(timestamp)) {
                            return true;
                        }
                    }
                    return false;
                }
            });

                    if (logs != null) {
                    for (File file : logs) {
                        file.delete();
                    }
                    }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    
    public static boolean isEnable() {
        return isEnable;
    }
    
    public static void enable() {
        setEnable(true);
    }
    
    public static void disable() {
        setEnable(false);
    }

    private static void setEnable(boolean isEnable) {
        LogWriter.isEnable = isEnable;
    }

    public static class TestCase {
        
        private static TestCase instance;
        
        private int testCaseIndex;
        private String testCaseName;
        private String resultInfo;
        private boolean testResult;
        
        private TestCase(int index, String name, String resInfo, boolean result) {
            testCaseIndex = index;
            testCaseName = name;
            resultInfo = resInfo;
            testResult = result;
        }
        
        public synchronized static TestCase getSingletonInstanse(int index, String name, String resultInfo, boolean result) {
            if (instance == null) {
                instance = new TestCase(index, name, resultInfo, result);
            } else {
                instance.testCaseIndex = index;
                instance.testCaseName = name;
                instance.resultInfo = resultInfo;
                instance.testResult = result;
            }
            return instance;
        }

        public String getResultInfo() {
            return resultInfo;
        }

        public void setResultInfo(String resultInfo) {
            this.resultInfo = resultInfo;
        }

        public boolean isTestResult() {
            return testResult;
        }

        public void setTestResult(boolean testResult) {
            this.testResult = testResult;
        }

        public int getTestCaseIndex() {
            return testCaseIndex;
        }

        public void setTestCaseIndex(int testCaseIndex) {
            this.testCaseIndex = testCaseIndex;
        }

        public String getTestCaseName() {
            return testCaseName;
        }

        public void setTestCaseName(String testCaseName) {
            this.testCaseName = testCaseName;
        }

    }
}
